#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2017-05-03 14:40:01
# @Author  : Your Name (you@example.org)
# @Link    : http://example.org
# @Version : $Id$

import os
import sys
import json
# import ConfigParser
import configparser
import re


def cur_file_dir():
    # 获取脚本路径
    path = sys.path[0]
    # 判断为脚本文件还是py2exe编译后的文件，如果是脚本文件，则返回的是脚本的目录，如果是py2exe编译后的文件，则返回的是编译后的文件路径
    if os.path.isdir(path):
        return path
    elif os.path.isfile(path):
        return os.path.dirname(path)


# 读取已有设备信息
dconf = configparser.ConfigParser()
conf_name = "blackmagic.cfg"
# conf_dir = "C:\Users\Public"
conf_dir = cur_file_dir()
# conf_dir = os.path.join()
conf_path = os.path.join(conf_dir, conf_name)

dconf.read(conf_path)


def conf_check():
    if os.path.exists(conf_dir):
        sections = dconf.sections()
        if 'devices' in sections:
            if not conf_read("devices", "dlist"):
                dconf.set("devices", "dlist", "[]")
                dconf.write(open(conf_path, "w"))

        else:
            dconf.add_section("devices")
            dconf.set("devices", "dlist", "[]")
            dconf.write(open(conf_path, "w"))
    else:
        os.makedirs(conf_path)
        dconf.set("devices")


def conf_write(section, option, oval):
    # dlist = json.loads(conf_read(section, option))
    dconf.set(section, option, oval)
    dconf.write(open(conf_path, "w"))


def conf_read(section, option):
    try:
        o = dconf.get(section, option)
    except Exception as e:
        print(e)
        return False
        print(o)
    print(type(o))
    return o


conf_check()
# a = json.loads(conf_read("devices", "dlist"))

# IP检查


def checkip(ip):
    p = re.compile(
        '^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$')
    if p.match(ip):
        return True
    else:
        return False

# telnet 调用
import socket
import telnetlib
import time


# 命令列表

# telnet接收的回调等待时间
stime = 0.2
lstime = 2
port = 9993


# 回调信息匹配
ok = "200 ok\r\n"
socket_error = u"连接设备失败，请检查设备是否开启，以及网络是否通畅"
re_dict = {
    "200 ok\r\n": u"命令发送成功",
    "100 syntax error\r\n" : "命令语法错误",
    "101 unsupported parameter\r\n": u"不支持的参数",
    "102 invalid value\r\n": u"错误的输入值，无效命令",
    "103 unsupported\r\n": u"不支持此功能",
    "104 disk full\r\n": u"磁盘已满",
    "105 no disk\r\n": u"此插槽无硬盘",
    "106 disk error\r\n": "磁盘错误",
    "107 timeline empty\r\n": u"请检查设备上是否有录像片段存在",
    "109 out of range\r\n": u"超出范围",
    "110 no input\r\n": u"没有输入源",
    "111 remote control disabled\r\n": u"未启用远程控制。",
    "120 connection rejected\r\n": u"连接被拒绝",
    "150 invalid state\r\n": u"无效状态"
}


def tel(dip, command, stime=stime):
    try:
        tn = telnetlib.Telnet(dip, port=port)
        time.sleep(stime)
        msg = tn.read_very_eager()
        tn.write(command)
        time.sleep(stime)
        msg = tn.read_very_eager()
        print(msg.__repr__())
        return msg
    except socket.error:
        return socket_error


from PyQt5 import QtGui, QtWidgets
from PyQt5 import QtCore, uic

# from PyQt4 import QtGui
# from PyQt4 import QtCore, uic


try:
    sys.path.append("C:\python27\Lib\site-packages")
except Exception as e:
    print(e)


# load ui
def resource_path(relative):
    if hasattr(sys, "_MEIPASS"):
        return os.path.join(sys._MEIPASS, relative)
        # print (relative)
    # return os.path.join(relative)
    return os.path.join(cur_file_dir(), relative)

bmui = resource_path('blackmagic.ui')
bmui_form_class, bmui_base_class = uic.loadUiType(bmui)


addui = resource_path('adddevice.ui')
addui_form_class, addui_base_class = uic.loadUiType(addui)


class AddDevice(addui_base_class, addui_form_class):

    def __init__(self):
        super(addui_base_class, self).__init__()
        self.setupUi(self)
        self.button_cancel.clicked.connect(self.close)
        self.button_add.clicked.connect(self.dadd)

    # 添加设备
    def dadd(self):
        dip = str(self.input_ip.text())
        dlist = json.loads(conf_read("devices", "dlist"))
        if checkip(dip):
            if dip in dlist:
                self.label_msg.setText(u"该ip地址已存在")
            else:
                dlist.append(dip)
                dlist.sort()
                conf_write('devices', 'dlist', json.dumps(dlist))
                self.label_msg.setText(u"添加成功")
        else:
            self.label_msg.setText(u"输入内容不正确，请以正确的格式输入ip地址")


class MainControl(bmui_base_class, bmui_form_class):

    def __init__(self):
        super(bmui_base_class, self).__init__()
        self.setupUi(self)
        self.button_addd.clicked.connect(self.add_device)
        self.button_removed.clicked.connect(self.rem_device)
        self.button_clipshow.clicked.connect(self.show_clips)
        self.button_remoteon.clicked.connect(self.set_remote_on)
        self.button_showconfig.clicked.connect(self.show_config)
        # 视频音频格式调整
        self.button_VHDMI.clicked.connect(self.video_input_hdmi)
        self.button_VSDI.clicked.connect(self.video_input_sdi)
        self.button_Vcomponent.clicked.connect(self.video_input_component)
        self.button_Sembedded.clicked.connect(self.audio_input_embedded)
        self.button_SXLR.clicked.connect(self.audio_input_xlr)
        self.button_SRCA.clicked.connect(self.audio_input_rca)
        self.button_file_format.clicked.connect(self.file_format)
        # self.devicelist.itemClicked.connect()
        # self.button_disklist.clicked.connect(self.disk_list)
        self.button_record.clicked.connect(self.record)
        self.button_stop.clicked.connect(self.stop)
        self.button_play.clicked.connect(self.play)
        self.button_play_single.clicked.connect(self.play_single)
        self.button_preview.clicked.connect(self.back_to_input)
        self.button_play_loop.clicked.connect(self.play_loop)
        self.button_goto_play.clicked.connect(self.goto_play)
        # self.button_goto_play.clicked.connect(self.back_to_input)
        # self.button_disk.clicked.connect(self.disk_try)
        self.button_slot1.clicked.connect(self.slot_1)
        self.button_slot2.clicked.connect(self.slot_2)
        self.button_goto_play.clicked.connect(self.goto_play)
        self.msg_num = 0

    def show_devices(self):
        dlist = json.loads(conf_read("devices", "dlist"))
        if len(dlist) > 0:
            for d in dlist:
                self.devicelist.addItem(d)
        else:
            pass

    # 添加设备
    def add_device(self):
        ad = AddDevice()
        ad.exec_()
        self.devicelist.clear()
        self.show_devices()

    # 移除选中的设备
    def rem_device(self):
        dlist = json.loads(conf_read("devices", "dlist"))
        items = self.devicelist.selectedItems()
        if len(items) > 0:
            for item in items:
                if item.text() in dlist:
                    dlist.remove(item.text())
                    dlist.sort()
                    conf_write('devices', 'dlist', json.dumps(dlist))
                else:
                    print(u"请排查异常")
        else:
            pass
        self.devicelist.clear()
        self.show_devices()

    def show_msg(self, re, dip=u"提示"):
        self.msg_num += 1
        # self.msg.clear()
        # if re_dict.has_key(re):     #python2
        if re in re_dict:
            re = re_dict[re]
        self.msg.addItem(str(self.msg_num) + "  " + dip + " : " + re)

    def show_config(self):
        # command = "configuration\n"
        command = b"configuration\n"
        self.send_cmd(command)

    def show_clips(self):
        # command = "clips get\n"
        command = b"clips get\n"
        items = self.devicelist.selectedItems()
        if len(items) > 1:
            # self.cliplist.clear()
            self.show_msg(u"请不要多选设备")
        elif len(items) <= 0:
            # self.cliplist.clear()
            self.show_msg(u"请先在设备列表中选中设备")
        else:
            for item in items:
                dip = str(item.text())
            re = (tel(dip, command)).decode().split("\r\n")
            # re = tel(dip, command)
            # if re_dict.has_key(re):
            #     self.show_msg(re)
            # else:
            #     re = re.split("\r\n")
            if re[0] == '205 clips info:':
                self.cliplist.clear()
                clist = re[2:-2]
                for clip in clist:
                    self.cliplist.addItem(clip)
            else:
                self.show_msg(re[0] + "\r\n", dip)

    def get_dip(self):
        items = self.devicelist.selectedItems()
        if len(items) > 0:
            return [str(item.text()) for item in items]
        else:
            return False

    def send_cmd(self, cmd):
        self.msg.clear()
        dips = self.get_dip()
        # print(dips.__repr__())
        if dips:
            for dip in dips:
                re = tel(dip, cmd)
                print(type(re))
                self.show_msg(re.decode(), dip)
        else:
            self.show_msg(u"请选中设备, 再发送命令")

    def set_remote_on(self):
        # command = "remote:enable:true\n"
        command = b"remote:enable:true\n"
        self.send_cmd(command)

    def video_input_hdmi(self):
        # command = "configuration:video input: HDMI\n"
        command = b"configuration:video input: HDMI\n"
        self.send_cmd(command)
        self.preview()

    def video_input_sdi(self):
        # command = "configuration: video input: SDI\n"
        command = b"configuration: video input: SDI\n"
        self.send_cmd(command)
        self.preview()

    def video_input_component(self):
        # command = "configuration: video input: component\n"
        command = b"configuration: video input: component\n"
        self.send_cmd(command)
        self.preview()

    def audio_input_embedded(self):
        # command = "configuration: audio input: embedded\n"
        command = b"configuration: audio input: embedded\n"
        self.send_cmd(command)

    def audio_input_xlr(self):
        # command = "configuration: audio input: XLR\n"
        command = b"configuration: audio input: XLR\n"
        self.send_cmd(command)

    def audio_input_rca(self):
        # command = "configuration: audio input: RCA\n"
        command = b"configuration: audio input: RCA\n"
        self.send_cmd(command)

    def file_format(self):
        fname = self.file_format_select.currentText()
        # fname = fname.encode()
        # print (type(fname))
        # command = "configuration: file format:" + fname + "\n"
        command = b"configuration: file format:" + fname.encode() + b"\n"
        self.send_cmd(command)

    def disk_list(self):
        try:
            command = b"disk list\n"
            dips = self.get_dip()
            # print (dips)
            if dips:
                for dip in dips:
                    dinfo = tel(dip, command, lstime)
                # print (123)
                # print (type(dinfo))
                dinfo = dinfo.decode()
                re = dinfo.split('\r\n')
                self.msg.clear()
                for m in re[:-2]:
                    self.show_msg(m, dip)
        except Exception as e:
            print (e)

    def record(self):

        # command = "record\n"
        command = b"record\n"
        self.send_cmd(command)

    def stop(self):
        # command = "stop\n"
        command = b"stop\n"
        self.send_cmd(command)


    def preview(self):
        command = b"preview:enable:true\n"
        self.send_cmd(command)

    def play(self):
        # command = "play\n"
        command = b"play\n"
        self.send_cmd(command)

    def play_single(self):
        # command = "play:single clip:true\n"
        command = b"play:single clip:true\n"
        self.send_cmd(command)

    def play_loop(self):
        # command = "play:loop:true\n"
        command = b"play:loop:true\n"
        self.send_cmd(command)

    def goto_play(self):
        items = self.cliplist.selectedItems()
        print(items)
        if len(items) == 1:
            for item in items:
                clipid = str(item.text()).split(':')[0]
            print (type(clipid.encode()))
            command = b"goto: clip id:" + clipid.encode() + b"\n"
            print (command)
            self.send_cmd(command)
            self.play()
        else:
            self.show_msg(u"请先选中片段")
        # command = b"clip get\n"
        # command = b"goto:clip id:1\n"
        # self.send_cmd(command)

    def back_to_input(self):
        command = b"configuration\n"
        self.msg.clear()
        dips = self.get_dip()
        # print(dips.__repr__())
        if dips:
            for dip in dips:
                re = tel(dip, command)
                re = re.decode().split("\r\n")
                print (re)
                if re[0]  == "211 configuration:":
                    if re[2] == 'video input: SDI':
                        self.video_input_sdi()
                    elif re[2] == 'video input: HDMI':
                        self.video_input_hdmi()
                    elif re[2] == 'video input: component':
                        self.video_input_component
                    else:
                        self.show_msg(u"未找到匹配的输入，请手动调整")

        



    # def disk_try(self):
    #     command = b"disk info\n"
    #     command = b"slot info\n"
    #     command = b"slot info\n"
    #     command = b"play\n"
    #     command = b"slot info:2\n"
    #     command = b"slot select: slot id:1\n"
    #     command = b"slot select: slot id:2\n"
    #     command = b"jog : " + b"timecode" + b"\n"
    #     self.send_cmd(command)

    def slot_1(self):
        command = b"slot select: slot id:1\n"
        self.send_cmd(command)

    def slot_2(self):
        command = b"slot select: slot id:2\n"
        self.send_cmd(command)

def main():
    app = QtWidgets.QApplication(sys.argv)
    window = MainControl()
    window.show_devices()
    window.show()
    # dl = dir(window.devicelist)
    # for d in dl:
    #     print d
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
